XML GenerationThe preferred way to generate XML files with XDoclet is to use Jelly. There are several reasons for this:
XML validationThe XMLGenerator class augments the JellyGenerator with XML validation logic, using Sun's MSV. JellyGenerator will (optionally) invoke MSV after the generation is done, to verify that the generated XML complies with the DTD/Schema. If MSV reports an error, it will be extremely difficult to implement an algorithm that could match this back to what @tag (or possibly Ant parameter) that was incorrect or missing. The best that can be done is to point the user to the source code and try to figure it out. -Or implement some additional validation logic in the generator. The MSV library is quite big, and we shouldn't force people to have it installed. Therefore, we need to cope with situations where it (and its secondary libraries) are not on the classpath. There should also be a switch to turn it on and off. If it's set to on, but not on classpath, an exception should be thrown, saying "either put MSV on the classpath or turn off validation". DocumentationAll the code generated by XGG must be well documented, so it's easy to use. The plugin developer needs to know about the generated Java bean API, and the user needs to know about the generator options, such as what DTD/XSD version it supports, and how to tell which one you want. ImplementationXGG will use Zeus as part of the generation process. Zeus has excellent support for DTDs, and we should extend it to support Relax NG (which is easier than XML Schema). If you want to use XGG with an XML Schema, it should first be converted to Relax NG using Sun's rngconv. This conversion should be done by the enhanced Zeus (if necessary) and it should remember the original Schema declaration, because that's what we want to declare in the XML that Jelly will generate. We'll modify Zeus so that it generates simple interfaces instead of java classes as it does today. These interfaces will eventually be thrown away, and serve as an intermediate result. Then we'll use a simplified version of the current XMLFacade plugin (which will be merged into XGG) that parses all the Zeus-generated APIs and generates a new "Union" API with concrete classes, and special tags and comments indicating what classes and methods are appliccable for what versions of the DTD/Schema. Now we can throw away the classes Zeus generated. With this "Union" API (and its special "version" tags) we can generate the Jelly script and the XMLGenerator subclass. We'll reuse code from the early XGG initiative for this. In stead of using Velocity to generate Velocity, we'll use Jelly to generate Jelly. This is a little bit tricky. We must use some special charaters in the generated script (so Jelly doesn't gobble them) and use Ant's replace task afterwards. That's OK, and it actually makes it easier to read the jelly generating jelly script. The final result is a nice Union API, a Jelly script and a skeletal Generator class that knows how to deal with the different versions of the DTD/Schema, and can invoke MSV to post-validate. The only thing the plugin developer needs to do now is to subclass the generator and fill the "Union" API with data (using xjavadoc). This approach will reduce the size of the plugin dramatically. the ejb-jar plugin (with support for 1.1 and 2.0) was 984 KB. The new size will be 100-150 KB, which is OK. While the internals of XGG is a bit complex, it won't be for the plugin developer, and that's the most important. XGG should be wrapped in an Ant task so it can be easily used by Ant people. In fact, the entire XDoclet SDK should be Ant tasks!!!!!!!!!!!!!!! |